

class CEntityEventHandler
{
    
private:
    
    class CGenericClass;
    
    typedef void (CGenericClass::*GenericMemberFuncType)(CEntity*,CEntityEvent event);
    
    CGenericClass* m_pObject;
    GenericMemberFuncType m_mfpMemberFunction;
    
public:
    
    //TODO: Add assignment operator, copy constructor etc. 
    
    template<class T>
    CEntityEventHandler(T* pObject, void (T::*mfpMemberFunc)(CEntity*,CEntityEvent event))
    {
        
        m_mfpMemberFunction = reinterpret_cast<GenericMemberFuncType>(mfpMemberFunc);
        m_pObject = reinterpret_cast<CGenericClass*>(pObject);
        
    }
    
    void raiseEvent(CEntity* pEntity, CEntityEvent event)
    {
        return (m_pObject->*(m_mfpMemberFunction))(pEntity, event);
    }
    
    //void operator() (CEntity* pEntity, CEvent event) const {
	//return (m_pObject->*(m_mfpMemberFunction))(pEntity, event); }
    
};

class CEntityEvent
{
    
public:
    
    //TODO: Add type and other required information
    
private:
    
    
    
};

//In Engine
//---------
class CEntity
{
    
public:
    
    CEntity(CEntityEventHandler ehEventHandler);
    
    void update()
    {
        
        if (bCollided) {
            
            CEntityEvent event;
            //event.setType(EV_COLLISION);
            //event.setOtherEntity(pOtherEnt);
            //event.setPos(vPos);
            //...
            
            m_EventHandler.raiseEvent(this, event);
            
        }
        
    }
    
private:
    
    CEntityEventHandler m_EventHandler;
    
};

//TODO: Think about using C# and using real delegates instead

//In Game
//-------
class CCar
{
    
    friend class CEntity;
    
public:
    
    CCar()
    {
        
        m_pBody = Game.addEntity( CEntity( /*...*/ CEntityEventHandler(this, &onBodyEvent)) );
        
        //m_pBody = Game.addEntity( CEntity( /*...*/ &onBodyEvent);
        //m_pWheel[0] = Game.addEntity( CEntity( /*...*/ &onWheelEvent);
        //m_pWheel[1] = Game.addEntity( CEntity( /*...*/ &onWheelEvent);
        //TODO: Look up member function pointers
        
    }
    
private:
    
    //TODO: Work out what to do as static members can't access non-static data
    
    //TODO: Think about replacing event with a string
    void onBodyEvent(CEntity* pEntity, CEntityEvent event)
    {
        
        //TODO: Think about logic responses and physical responses
        //      Ideally have only logical responses needed in here
        
        switch (event.getID()) {
            case EV_COLLIDE:
                
                pEntity
                
                break;
            case default:
                break;
        }
        
    }
    
    void onWheelEvent()
    {
        
        
        
    }
    
    CEntity* m_pBody;
    CEntity* m_pWheels[2];
    
};
